<?php

/**
 * 
 * @desc This class defines object models with validation support
 * @author Barbushin Sergey http://www.linkedin.com/in/barbushin
 * 
 */
class Model {

	public function __construct(array $properties = array()) {
		$this->setByArray($properties);
	}

	public function setByArray(array $properties) {
		foreach ($properties as $property => $value) {
			$this->$property = $value;
		}
	}

	public function asArray($notEmpty = false, $scalarsOnly = false) {
		$properties = get_object_vars($this);
		foreach ($properties as $name => $value) {
			if (($notEmpty && is_null($value)) || ($scalarsOnly && !is_scalar($value))) {
				unset($properties[$name]);
			}
		}
		return $properties;
	}

	/***************************************************************
	 MAGICS
	 **************************************************************/
	
	public function __get($property) {
		throw new Exception('Unkown property "' . $property . '"');
	}

	public function __call($property, array $value) {
		$this->$property = isset($value[0]) ? $value[0] : null;
		return $this;
	}

	public function __unset($property) {
		$this->$property = null;
	}

	/***************************************************************
	 VALIDATION
	 **************************************************************/
	
	public function validate($properties = null, $throwException = true) {
		$validator = $this->getValidator();
		return $validator ? $validator->isValid($this->asArray(), $properties, $throwException) : true;
	}
	
	public function getValidator() {
		static $validator = null;
		if (is_null($validator)) {
			$validator = $this->initValidator();
		}
		return $validator;
	}

	protected function initValidator() {
		return false;
	}

	public function getValidationErrors() {
		return $this->getValidator() ? $this->getValidator()->getErrors() : array();
	}
}
